# 这是一个示例 Python 脚本。

# 按 Shift+F10 执行或将其替换为您的代码。
# 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。

from flask import Flask, render_template, render_template_string, redirect, url_for, flash, session, request, g, jsonify
import os
import sys
import logging
from functools import wraps
from werkzeug.security import generate_password_hash, check_password_hash
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from src.db_util import db_util, DBUtil, resource_path
from src.db_init import init_database
import sqlite3
from sqlite3 import OperationalError

# 配置日志 - 修改为输出到文件和控制台
log_file = os.path.join(os.path.abspath("."), 'pms.log')
logging.basicConfig(
    level=logging.DEBUG,  # 提高日志级别以查看更多信息
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(log_file),
        logging.StreamHandler()  # 添加控制台输出
    ]
)

# 创建数据库工具类的单例实例
db_util = DBUtil()

app = Flask(__name__, 
           static_folder=resource_path(os.path.join('src', 'static')),
           template_folder=resource_path('templates'))
app.secret_key = os.urandom(24)
app.config['SESSION_TYPE'] = 'filesystem'

# 在应用启动时初始化数据库 - 但这里不调用，移到if __name__ == "__main__"中

# 登录页面
@app.route('/login', methods=['GET', 'POST'])
def login():
    try:
        if request.method == 'POST':
            username = request.form.get('username')
            password = request.form.get('password')
            db = g.db
            if not db:
                logging.error("数据库连接不可用")
                flash('系统错误：数据库连接不可用', 'danger')
                return render_template('login.html')
            user = db.execute_query("SELECT * FROM PMS_USER WHERE username = ?", (username,))
            if user and len(user) > 0:
                if user[0]['password'] == password:
                    session['user_id'] = user[0]['id']
                    session['username'] = user[0]['username']
                    session['real_name'] = user[0]['real_name']
                    session['is_admin'] = 1
                    db.execute_update("UPDATE PMS_USER SET last_login_time = datetime('now') WHERE id = ?", (user[0]['id'],))
                    flash('登录成功', 'success')
                    next_url = request.args.get('next')
                    if next_url and next_url.startswith('/'):
                        return redirect(next_url)
                    return redirect(url_for('index'))
                else:
                    flash('密码错误', 'danger')
                    return render_template('login.html')
            else:
                flash('用户名不存在', 'danger')
                return render_template('login.html')
        return render_template('login.html')
    except OperationalError as oe:
        error_msg = str(oe)
        if "unable to open database file" in error_msg:
            return render_template(
                "db_error.html",
                error_message="数据库文件不存在，请先点击下方按钮【创建数据库文件】。"
            ), 500
        elif "no such table" in error_msg:
            return render_template(
                "db_error.html",
                error_message="数据库文件已存在，但表未初始化，请先点击下方按钮【初始化数据库】。"
            ), 500
        else:
            return render_template(
                "db_error.html",
                error_message=f"数据库错误: {error_msg}"
            ), 500
    except Exception as e:
        logging.exception(f"登录页面异常: {str(e)}")
        return render_template(
            "db_error.html",
            error_message=f"系统错误: {str(e)}"
        ), 500

# 登录验证装饰器
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            # 检查是否已经有登录提示，避免重复闪现
            flashed_messages = session.get('_flashes', [])
            login_warning_exists = any(msg[1] == '请先登录' for msg in flashed_messages)
            
            if not login_warning_exists:
                flash('请先登录', 'warning')
            return redirect(url_for('login', next=request.url))
        return f(*args, **kwargs)
    return decorated_function

# 管理员权限验证装饰器
def admin_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            # 检查是否已经有登录提示，避免重复闪现
            flashed_messages = session.get('_flashes', [])
            login_warning_exists = any(msg[1] == '请先登录' for msg in flashed_messages)
            
            if not login_warning_exists:
                flash('请先登录', 'warning')
            return redirect(url_for('login', next=request.url))
        if session.get('is_admin') != 1:
            flash('需要管理员权限', 'danger')
            return redirect(url_for('index'))
        return f(*args, **kwargs)
    return decorated_function

# 首页
@app.route('/')
def index():
    return redirect(url_for('project_list'))

# 登出
@app.route('/logout')
def logout():
    session.clear()
    flash('已退出登录', 'info')
    return redirect(url_for('login'))

# ======== 项目管理 ========
# 项目列表
@app.route('/projects')
@login_required
def project_list():
    # 注意：已从使用全局db变量修改为使用g.db
    # 这种修改应在所有路由中进行，确保正确使用请求范围内的数据库连接
    db = g.db  # 从g中获取数据库连接
    
    sql = """
    SELECT p.*, pc.name as category_name, s.name as status_name, u.real_name as creator
    FROM PMS_PROJECT p
    LEFT JOIN PMS_PROJECT_CATEGORY pc ON p.category_id = pc.id
    LEFT JOIN PMS_STATUS s ON p.status_id = s.id
    LEFT JOIN PMS_USER u ON p.create_user_id = u.id
    ORDER BY p.id DESC
    """
    
    projects = db.execute_query(sql)
    app.logger.info(f"项目查询: 获取到 {len(projects)} 个项目")
    
    return render_template('project/list.html', projects=projects)

# 项目详情
@app.route('/projects/<int:project_id>')
@login_required
def project_detail(project_id):
    # 从g获取数据库连接
    db = g.db
    
    # 获取项目详情
    sql = """
    SELECT p.*, pc.name as category_name, s.name as status_name, 
           cu.real_name as creator, uu.real_name as updater
    FROM PMS_PROJECT p
    LEFT JOIN PMS_PROJECT_CATEGORY pc ON p.category_id = pc.id
    LEFT JOIN PMS_STATUS s ON p.status_id = s.id
    LEFT JOIN PMS_USER cu ON p.create_user_id = cu.id
    LEFT JOIN PMS_USER uu ON p.update_user_id = uu.id
    WHERE p.id = ?
    """
    project = db.execute_query(sql, (project_id,))
    
    if not project:
        flash('项目不存在', 'danger')
        return redirect(url_for('project_list'))
    
    # 获取项目的部署信息
    sql = """
    SELECT d.*, dt.name as deploy_type_name, u.real_name as creator
    FROM PMS_DEPLOYMENT d
    LEFT JOIN PMS_DEPLOY_TYPE dt ON d.deploy_type_id = dt.id
    LEFT JOIN PMS_USER u ON d.create_user_id = u.id
    WHERE d.project_id = ?
    """
    deployments = db.execute_query(sql, (project_id,))
    
    return render_template('project/detail.html', project=project[0], deployments=deployments)

# 创建/编辑项目
@app.route('/projects/edit/<int:project_id>', methods=['GET', 'POST'])
@app.route('/projects/new', methods=['GET', 'POST'])
@login_required
def project_edit(project_id=None):
    # 从g获取数据库连接
    db = g.db
    
    # 获取项目分类
    categories = db.execute_query("SELECT * FROM PMS_PROJECT_CATEGORY ORDER BY name")
    # 获取项目状态
    statuses = db.execute_query("SELECT * FROM PMS_STATUS ORDER BY name")
    
    # 新建项目
    if project_id is None:
        if request.method == 'POST':
            name = request.form.get('name')
            code = request.form.get('code')
            category_id = request.form.get('category_id')
            status_id = request.form.get('status_id')
            git_url = request.form.get('git_url')
            description = request.form.get('description')
            
            # 验证项目代码唯一性
            existing = db.execute_query("SELECT * FROM PMS_PROJECT WHERE code = ?", (code,))
            if existing:
                flash('项目代码已存在', 'danger')
                return render_template('project/edit.html', project={}, categories=categories, statuses=statuses)
            
            # 插入数据
            sql = """
            INSERT INTO PMS_PROJECT (name, code, category_id, status_id, git_url, description, 
                                     create_time, create_user_id, update_time, update_user_id)
            VALUES (?, ?, ?, ?, ?, ?, datetime('now'), ?, datetime('now'), ?)
            """
            db.execute_update(sql, (name, code, category_id, status_id, git_url, description, 
                                   session['user_id'], session['user_id']))
            
            flash('项目创建成功', 'success')
            return redirect(url_for('project_list'))
        
        return render_template('project/edit.html', project={}, categories=categories, statuses=statuses)
    
    # 编辑项目
    else:
        project = db.execute_query("SELECT * FROM PMS_PROJECT WHERE id = ?", (project_id,))
        if not project:
            flash('项目不存在', 'danger')
            return redirect(url_for('project_list'))
        
        if request.method == 'POST':
            name = request.form.get('name')
            code = request.form.get('code')  # 允许修改项目代码
            category_id = request.form.get('category_id')
            status_id = request.form.get('status_id')
            git_url = request.form.get('git_url')
            description = request.form.get('description')
            
            # 验证项目代码唯一性（排除当前项目）
            existing = db.execute_query("SELECT * FROM PMS_PROJECT WHERE code = ? AND id != ?", (code, project_id))
            if existing:
                flash('项目代码已存在', 'danger')
                return render_template('project/edit.html', project=project[0], categories=categories, statuses=statuses)
            
            # 更新数据
            sql = """
            UPDATE PMS_PROJECT 
            SET name = ?, code = ?, category_id = ?, status_id = ?, git_url = ?, description = ?, 
                update_time = datetime('now'), update_user_id = ?
            WHERE id = ?
            """
            db.execute_update(sql, (name, code, category_id, status_id, git_url, description, 
                                   session['user_id'], project_id))
            
            flash('项目更新成功', 'success')
            return redirect(url_for('project_detail', project_id=project_id))
        
        return render_template('project/edit.html', project=project[0], categories=categories, statuses=statuses)

# ======== 部署信息管理 ========
# 创建/编辑部署信息
@app.route('/deployments/edit/<int:deployment_id>', methods=['GET', 'POST'])
@app.route('/projects/<int:project_id>/deployments/new', methods=['GET', 'POST'])
@login_required
def deployment_edit(deployment_id=None, project_id=None):
    # 从g获取数据库连接
    db = g.db
    
    # 获取部署类型选项
    deploy_types = db.execute_query("SELECT * FROM PMS_DEPLOY_TYPE ORDER BY id")
    
    if deployment_id:
        # 编辑部署信息
        deployment = db.execute_query("SELECT * FROM PMS_DEPLOYMENT WHERE id = ?", (deployment_id,))
        if not deployment:
            flash('部署信息不存在', 'danger')
            return redirect(url_for('project_list'))
        deployment = deployment[0]
        project_id = deployment['project_id']
    else:
        if not project_id:
            flash('参数错误', 'danger')
            return redirect(url_for('project_list'))
        
        # 新建部署信息
        deployment = {
            'id': None,
            'project_id': project_id,
            'deploy_type_id': deploy_types[0]['id'] if deploy_types else None,
            'host_ip': '',
            'username': '',
            'directory': '',
            'start_command': '',
            'stop_command': '',
            'status_check_command': '',
            'log_path': '',
            'description': ''
        }
    
    # 获取项目信息
    project = db.execute_query("SELECT * FROM PMS_PROJECT WHERE id = ?", (project_id,))
    if not project:
        flash('项目不存在', 'danger')
        return redirect(url_for('project_list'))
    
    if request.method == 'POST':
        deploy_type_id = request.form.get('deploy_type_id')
        host_ip = request.form.get('host_ip')
        username = request.form.get('username')
        directory = request.form.get('directory')
        start_command = request.form.get('start_command')
        stop_command = request.form.get('stop_command')
        status_check_command = request.form.get('status_check_command')
        log_path = request.form.get('log_path')
        description = request.form.get('description')
        
        # 验证输入
        if not deploy_type_id or not host_ip or not directory:
            flash('请填写必填字段', 'danger')
        else:
            if deployment_id:
                # 更新部署信息
                sql = """
                UPDATE PMS_DEPLOYMENT 
                SET deploy_type_id = ?, host_ip = ?, username = ?, directory = ?,
                    start_command = ?, stop_command = ?, status_check_command = ?,
                    log_path = ?, description = ?, update_user_id = ?, update_time = datetime('now')
                WHERE id = ?
                """
                params = (deploy_type_id, host_ip, username, directory, start_command, 
                          stop_command, status_check_command, log_path, description, 
                          session['user_id'], deployment_id)
                result = db.execute_update(sql, params)
                if result is not None:
                    flash('部署信息更新成功', 'success')
                    return redirect(url_for('project_detail', project_id=project_id))
                else:
                    flash('部署信息更新失败', 'danger')
            else:
                # 创建部署信息
                sql = """
                INSERT INTO PMS_DEPLOYMENT (project_id, deploy_type_id, host_ip, username, directory,
                                           start_command, stop_command, status_check_command, log_path,
                                           description, create_user_id, create_time)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
                """
                params = (project_id, deploy_type_id, host_ip, username, directory, 
                          start_command, stop_command, status_check_command, log_path, 
                          description, session['user_id'])
                result = db.execute_update(sql, params)
                if result is not None:
                    flash('部署信息创建成功', 'success')
                    return redirect(url_for('project_detail', project_id=project_id))
                else:
                    flash('部署信息创建失败', 'danger')
    
    return render_template('deployment/edit.html', deployment=deployment, project=project[0], deploy_types=deploy_types)

# 删除部署信息
@app.route('/deployments/delete/<int:deployment_id>', methods=['POST'])
@login_required
def deployment_delete(deployment_id):
    deployment = db.execute_query("SELECT project_id FROM PMS_DEPLOYMENT WHERE id = ?", (deployment_id,))
    if not deployment:
        flash('部署信息不存在', 'danger')
        return redirect(url_for('project_list'))
    
    project_id = deployment[0]['project_id']
    
    result = db.execute_update("DELETE FROM PMS_DEPLOYMENT WHERE id = ?", (deployment_id,))
    if result is not None:
        flash('部署信息删除成功', 'success')
    else:
        flash('部署信息删除失败', 'danger')
    
    return redirect(url_for('project_detail', project_id=project_id))

# ======== 系统配置管理 ========
# 部署类型管理
@app.route('/config/deploy-types', methods=['GET', 'POST'])
@login_required
@admin_required
def config_deploy_types():
    # 从g获取数据库连接
    db = g.db
    
    if request.method == 'POST':
        action = request.form.get('action')
        
        if action == 'add':
            name = request.form.get('name')
            description = request.form.get('description', '')
            
            if not name:
                flash('请填写类型名称', 'danger')
            else:
                # 检查是否已存在
                check = db.execute_query("SELECT id FROM PMS_DEPLOY_TYPE WHERE name = ?", (name,))
                if check:
                    flash('类型名称已存在', 'danger')
                else:
                    result = db.execute_update("INSERT INTO PMS_DEPLOY_TYPE (name, description) VALUES (?, ?)", 
                                              (name, description))
                    if result is not None:
                        flash('部署类型添加成功', 'success')
                    else:
                        flash('部署类型添加失败', 'danger')
        
        elif action == 'edit':
            type_id = request.form.get('id')
            name = request.form.get('name')
            description = request.form.get('description', '')
            
            if not type_id or not name:
                flash('参数错误', 'danger')
            else:
                # 检查是否存在同名但不同ID的记录
                check = db.execute_query("SELECT id FROM PMS_DEPLOY_TYPE WHERE name = ? AND id != ?", (name, type_id))
                if check:
                    flash('类型名称已存在', 'danger')
                else:
                    result = db.execute_update("UPDATE PMS_DEPLOY_TYPE SET name = ?, description = ? WHERE id = ?", 
                                              (name, description, type_id))
                    if result is not None:
                        flash('部署类型更新成功', 'success')
                    else:
                        flash('部署类型更新失败', 'danger')
        
        elif action == 'delete':
            type_id = request.form.get('id')
            
            if not type_id:
                flash('参数错误', 'danger')
            else:
                # 检查是否被使用
                check = db.execute_query("SELECT id FROM PMS_DEPLOYMENT WHERE deploy_type_id = ? LIMIT 1", (type_id,))
                if check:
                    flash('该部署类型已被使用，无法删除', 'danger')
                else:
                    result = db.execute_update("DELETE FROM PMS_DEPLOY_TYPE WHERE id = ?", (type_id,))
                    if result is not None:
                        flash('部署类型删除成功', 'success')
                    else:
                        flash('部署类型删除失败', 'danger')
    
    # 获取所有部署类型
    deploy_types = db.execute_query("SELECT * FROM PMS_DEPLOY_TYPE ORDER BY id")
    
    return render_template('config/deploy_types.html', deploy_types=deploy_types)

# 项目分类管理
@app.route('/config/project-categories', methods=['GET', 'POST'])
@login_required
@admin_required
def config_project_categories():
    # 从g获取数据库连接
    db = g.db
    
    if request.method == 'POST':
        action = request.form.get('action')
        
        if action == 'add':
            name = request.form.get('name')
            description = request.form.get('description', '')
            
            if not name:
                flash('请填写分类名称', 'danger')
            else:
                # 检查是否已存在
                check = db.execute_query("SELECT id FROM PMS_PROJECT_CATEGORY WHERE name = ?", (name,))
                if check:
                    flash('分类名称已存在', 'danger')
                else:
                    result = db.execute_update("INSERT INTO PMS_PROJECT_CATEGORY (name, description) VALUES (?, ?)", 
                                              (name, description))
                    if result is not None:
                        flash('项目分类添加成功', 'success')
                    else:
                        flash('项目分类添加失败', 'danger')
        
        elif action == 'edit':
            category_id = request.form.get('id')
            name = request.form.get('name')
            description = request.form.get('description', '')
            
            if not category_id or not name:
                flash('参数错误', 'danger')
            else:
                # 检查是否存在同名但不同ID的记录
                check = db.execute_query("SELECT id FROM PMS_PROJECT_CATEGORY WHERE name = ? AND id != ?", 
                                       (name, category_id))
                if check:
                    flash('分类名称已存在', 'danger')
                else:
                    result = db.execute_update("UPDATE PMS_PROJECT_CATEGORY SET name = ?, description = ? WHERE id = ?", 
                                              (name, description, category_id))
                    if result is not None:
                        flash('项目分类更新成功', 'success')
                    else:
                        flash('项目分类更新失败', 'danger')
        
        elif action == 'delete':
            category_id = request.form.get('id')
            
            if not category_id:
                flash('参数错误', 'danger')
            else:
                # 检查是否被使用
                check = db.execute_query("SELECT id FROM PMS_PROJECT WHERE category_id = ? LIMIT 1", (category_id,))
                if check:
                    flash('该项目分类已被使用，无法删除', 'danger')
                else:
                    result = db.execute_update("DELETE FROM PMS_PROJECT_CATEGORY WHERE id = ?", (category_id,))
                    if result is not None:
                        flash('项目分类删除成功', 'success')
                    else:
                        flash('项目分类删除失败', 'danger')
    
    # 获取所有项目分类
    categories = db.execute_query("SELECT * FROM PMS_PROJECT_CATEGORY ORDER BY id")
    
    return render_template('config/project_categories.html', categories=categories)

# 项目状态管理
@app.route('/config/status', methods=['GET', 'POST'])
@login_required
@admin_required
def config_status():
    # 从g获取数据库连接
    db = g.db
    
    if request.method == 'POST':
        action = request.form.get('action')
        
        if action == 'add':
            name = request.form.get('name')
            description = request.form.get('description', '')
            
            if not name:
                flash('请填写状态名称', 'danger')
            else:
                # 检查是否已存在
                check = db.execute_query("SELECT id FROM PMS_STATUS WHERE name = ?", (name,))
                if check:
                    flash('状态名称已存在', 'danger')
                else:
                    result = db.execute_update("INSERT INTO PMS_STATUS (name, description) VALUES (?, ?)", 
                                              (name, description))
                    if result is not None:
                        flash('项目状态添加成功', 'success')
                    else:
                        flash('项目状态添加失败', 'danger')
        
        elif action == 'edit':
            status_id = request.form.get('id')
            name = request.form.get('name')
            description = request.form.get('description', '')
            
            if not status_id or not name:
                flash('参数错误', 'danger')
            else:
                # 检查是否存在同名但不同ID的记录
                check = db.execute_query("SELECT id FROM PMS_STATUS WHERE name = ? AND id != ?", 
                                       (name, status_id))
                if check:
                    flash('状态名称已存在', 'danger')
                else:
                    result = db.execute_update("UPDATE PMS_STATUS SET name = ?, description = ? WHERE id = ?", 
                                              (name, description, status_id))
                    if result is not None:
                        flash('项目状态更新成功', 'success')
                    else:
                        flash('项目状态更新失败', 'danger')
        
        elif action == 'delete':
            status_id = request.form.get('id')
            
            if not status_id:
                flash('参数错误', 'danger')
            else:
                # 检查是否被使用
                check = db.execute_query("SELECT id FROM PMS_PROJECT WHERE status_id = ? LIMIT 1", (status_id,))
                if check:
                    flash('该项目状态已被使用，无法删除', 'danger')
                else:
                    result = db.execute_update("DELETE FROM PMS_STATUS WHERE id = ?", (status_id,))
                    if result is not None:
                        flash('项目状态删除成功', 'success')
                    else:
                        flash('项目状态删除失败', 'danger')
    
    # 获取所有项目状态
    statuses = db.execute_query("SELECT * FROM PMS_STATUS ORDER BY id")
    
    return render_template('config/status.html', statuses=statuses)

# 用户管理
@app.route('/users', methods=['GET', 'POST'])
@login_required
@admin_required
def user_list():
    # 从g获取数据库连接
    db = g.db
    
    # 获取所有用户
    users = db.execute_query("SELECT * FROM PMS_USER ORDER BY id")
    
    return render_template('user/list.html', users=users)

# 创建/编辑用户
@app.route('/users/edit/<int:user_id>', methods=['GET', 'POST'])
@app.route('/users/new', methods=['GET', 'POST'])
@login_required
@admin_required
def user_edit(user_id=None):
    # 从g获取数据库连接
    db = g.db
    
    if user_id:
        # 编辑用户
        user = db.execute_query("SELECT * FROM PMS_USER WHERE id = ?", (user_id,))
        if not user:
            flash('用户不存在', 'danger')
            return redirect(url_for('user_list'))
        user = user[0]
        # 不显示密码
        user['password'] = ''
    else:
        # 新建用户
        user = {
            'id': None,
            'username': '',
            'password': '',
            'real_name': '',
            'email': '',
            'phone': '',
            'status': 1
        }
    
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        real_name = request.form.get('real_name')
        email = request.form.get('email')
        phone = request.form.get('phone')
        status = request.form.get('status', 1)
        
        # 验证输入
        if not username:
            flash('请填写用户名', 'danger')
        else:
            if user_id:
                # 检查用户名是否已存在（排除当前用户）
                check = db.execute_query("SELECT id FROM PMS_USER WHERE username = ? AND id != ?", (username, user_id))
                if check:
                    flash('用户名已存在', 'danger')
                else:
                    # 更新用户
                    if password:  # 如果提供了新密码
                        sql = """
                        UPDATE PMS_USER 
                        SET username = ?, password = ?, real_name = ?, 
                            email = ?, phone = ?, status = ?
                        WHERE id = ?
                        """
                        params = (username, password, real_name, email, phone, status, user_id)
                    else:  # 不更新密码
                        sql = """
                        UPDATE PMS_USER 
                        SET username = ?, real_name = ?, 
                            email = ?, phone = ?, status = ?
                        WHERE id = ?
                        """
                        params = (username, real_name, email, phone, status, user_id)
                    
                    result = db.execute_update(sql, params)
                    if result is not None:
                        flash('用户更新成功', 'success')
                        return redirect(url_for('user_list'))
                    else:
                        flash('用户更新失败', 'danger')
            else:
                # 新用户必须提供密码
                if not password:
                    flash('请填写密码', 'danger')
                else:
                    # 检查用户名是否已存在
                    check = db.execute_query("SELECT id FROM PMS_USER WHERE username = ?", (username,))
                    if check:
                        flash('用户名已存在', 'danger')
                    else:
                        # 创建用户
                        sql = """
                        INSERT INTO PMS_USER (username, password, real_name, email, phone, status, create_time)
                        VALUES (?, ?, ?, ?, ?, ?, datetime('now'))
                        """
                        params = (username, password, real_name, email, phone, status)
                        result = db.execute_update(sql, params)
                        if result is not None:
                            flash('用户创建成功', 'success')
                            return redirect(url_for('user_list'))
                        else:
                            flash('用户创建失败', 'danger')
    
    return render_template('user/edit.html', user=user)

# 删除用户
@app.route('/users/delete/<int:user_id>', methods=['POST'])
@login_required
@admin_required
def user_delete(user_id):
    # 从g获取数据库连接
    db = g.db
    
    # 检查是否是当前登录用户
    if user_id == session.get('user_id'):
        flash('不能删除当前登录用户', 'danger')
        return redirect(url_for('user_list'))
    
    # 检查是否有关联数据
    check_project = db.execute_query("SELECT id FROM PMS_PROJECT WHERE create_user_id = ? OR update_user_id = ? LIMIT 1", 
                                   (user_id, user_id))
    check_deployment = db.execute_query("SELECT id FROM PMS_DEPLOYMENT WHERE create_user_id = ? OR update_user_id = ? LIMIT 1", 
                                      (user_id, user_id))
    
    if check_project or check_deployment:
        flash('该用户已有关联数据，无法删除', 'danger')
    else:
        result = db.execute_update("DELETE FROM PMS_USER WHERE id = ?", (user_id,))
        if result is not None:
            flash('用户删除成功', 'success')
        else:
            flash('用户删除失败', 'danger')
    
    return redirect(url_for('user_list'))

# 添加一个调试路由
@app.route('/debug-db')
@login_required
@admin_required
def debug_db():
    # 从g获取数据库连接
    db = g.db
    
    # 获取所有表及其记录数
    tables = db.get_tables()
    results = {}
    
    for table in tables:
        if table.startswith('PMS_'):  # 只检查应用相关表
            count = db.execute_query(f"SELECT COUNT(*) as count FROM {table}")
            results[table] = count[0]['count'] if count else 0
            
            # 获取前10条记录作为示例
            records = db.execute_query(f"SELECT * FROM {table} LIMIT 10")
            if records:
                results[f"{table}_sample"] = records
    
    # 检查项目列表查询
    project_sql = """
    SELECT p.*, pc.name as category_name, s.name as status_name, u.real_name as creator
    FROM PMS_PROJECT p
    LEFT JOIN PMS_PROJECT_CATEGORY pc ON p.category_id = pc.id
    LEFT JOIN PMS_STATUS s ON p.status_id = s.id
    LEFT JOIN PMS_USER u ON p.create_user_id = u.id
    ORDER BY p.id DESC
    """
    projects = db.debug_query(project_sql)
    results['projects_query'] = projects
    
    # 查询是否有用户
    users = db.debug_query("SELECT * FROM PMS_USER")
    results['users'] = users
    
    return render_template('debug.html', results=results)

# 添加临时调试路由
@app.route('/debug')
def debug():
    # 直接使用SQLite进行测试
    import sqlite3
    conn = sqlite3.connect('dist/pms.db')
    conn.row_factory = lambda cursor, row: {
        col[0]: row[idx] for idx, col in enumerate(cursor.description)
    }
    
    # 检查所有表的数据
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    tables = cursor.fetchall()
    
    results = {}
    for table in tables:
        table_name = table['name']
        cursor.execute(f"SELECT COUNT(*) as count FROM {table_name}")
        count = cursor.fetchone()['count']
        results[table_name] = count
        
        # 获取表的前10条记录
        if count > 0:
            cursor.execute(f"SELECT * FROM {table_name} LIMIT 10")
            records = cursor.fetchall()
            results[f"{table_name}_data"] = records
    
    # 特别检查项目列表查询
    project_sql = """
    SELECT p.*, pc.name as category_name, s.name as status_name, u.real_name as creator
    FROM PMS_PROJECT p
    LEFT JOIN PMS_PROJECT_CATEGORY pc ON p.category_id = pc.id
    LEFT JOIN PMS_STATUS s ON p.status_id = s.id
    LEFT JOIN PMS_USER u ON p.create_user_id = u.id
    ORDER BY p.id DESC
    """
    cursor.execute(project_sql)
    projects = cursor.fetchall()
    results['projects'] = projects
    
    conn.close()
    
    return f"""
    <pre>
    数据库调试信息:
    
    表数量: {len(tables)}
    
    表记录数:
    {str(results)}
    </pre>
    """

# 请求前连接数据库
@app.before_request
def before_request():
    """在请求开始前创建数据库连接并存储在g对象中"""
    try:
        # 使用单例实例
        g.db = db_util
        g.db.connect()  # 显式连接到数据库
        logging.debug("数据库连接已创建并存储在g.db中")
    except Exception as e:
        logging.exception(f"请求前连接数据库失败: {str(e)}")
        g.db = None  # 确保g.db在失败时设置为None

# 请求后关闭数据库连接
@app.teardown_request
def teardown_request(exception=None):
    """在请求结束时关闭数据库连接"""
    db_conn = getattr(g, 'db', None)
    if db_conn is not None:
        try:
            db_conn.close()
            logging.debug("数据库连接已关闭")
        except Exception as e:
            logging.error(f"关闭数据库连接时出错: {str(e)}")
    
    # 清除g对象中的数据库连接
    if hasattr(g, 'db'):
        g.db = None

# 删除项目
@app.route('/projects/delete/<int:project_id>', methods=['POST'])
@login_required
def project_delete(project_id):
    db = g.db  # 从g中获取数据库连接
    
    # 首先检查是否有关联的部署信息
    deployments = db.execute_query("SELECT COUNT(*) as count FROM PMS_DEPLOYMENT WHERE project_id = ?", (project_id,))
    if deployments and deployments[0]['count'] > 0:
        flash(f'无法删除项目：该项目有 {deployments[0]["count"]} 条部署信息。请先删除相关部署信息。', 'danger')
        return redirect(url_for('project_list'))
    
    # 删除项目
    result = db.execute_update("DELETE FROM PMS_PROJECT WHERE id = ?", (project_id,))
    if result is not None:
        flash('项目删除成功', 'success')
    else:
        flash('项目删除失败', 'danger')
    
    return redirect(url_for('project_list'))

# After the login route, add a simple diagnostic route
@app.route('/logintest')
def logintest():
    """简单的诊断路由，不使用模板直接返回HTML"""
    try:
        # 测试数据库连接
        db_status = "数据库连接正常" if g.db else "数据库连接失败"
        
        # 简单的HTML响应
        html = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>登录测试</title>
            <meta charset="utf-8">
        </head>
        <body>
            <h1>登录诊断页面</h1>
            <p>如果您看到此页面，说明基本路由处理正常。</p>
            <p>数据库状态: {db_status}</p>
            <p>请尝试 <a href="/login">访问登录页</a></p>
        </body>
        </html>
        """
        return html
    except Exception as e:
        return f"诊断页面错误: {str(e)}", 500

# After the logintest route, add a simple login route that uses our new template
@app.route('/login-simple', methods=['GET', 'POST'])
def login_simple():
    """简单的登录路由，使用不依赖base.html的简单模板"""
    try:
        if request.method == 'POST':
            username = request.form.get('username')
            password = request.form.get('password')
            
            # Test database connection
            if not hasattr(g, 'db') or g.db is None:
                logging.error("g.db is None in login_simple")
                flash('数据库连接失败', 'danger')
                return render_template('login_simple.html')
                
            # Query the user
            try:
                user = g.db.execute_query("SELECT * FROM PMS_USER WHERE username = ?", (username,))
                logging.info(f"User query result: {user}")
            except Exception as e:
                logging.exception(f"User query error: {str(e)}")
                flash(f'查询用户出错: {str(e)}', 'danger')
                return render_template('login_simple.html')
            
            if user and len(user) > 0:
                if user[0]['password'] == password:
                    session['user_id'] = user[0]['id']
                    session['username'] = user[0]['username']
                    session['real_name'] = user[0]['real_name']
                    session['is_admin'] = 1
                    flash('登录成功', 'success')
                    return redirect(url_for('index'))
                else:
                    flash('密码错误', 'danger')
            else:
                flash('用户名不存在', 'danger')
        
        return render_template('login_simple.html')
    except Exception as e:
        logging.exception(f"Simple login error: {str(e)}")
        return f"""
        <html>
        <body>
            <h1>登录页面错误</h1>
            <p>错误信息: {str(e)}</p>
            <p>请查看日志获取更多信息</p>
        </body>
        </html>
        """, 500

# 创建数据库文件
@app.route('/create-database', methods=['POST'])
def create_database():
    try:
        db_file_path = resource_path('pms.db')
        logging.info(f"准备创建数据库文件，路径: {db_file_path}")
        if os.path.exists(db_file_path):
            flash(f'数据库文件已存在: {db_file_path}', 'warning')
        else:
            db_dir = os.path.dirname(db_file_path)
            if not os.path.exists(db_dir):
                os.makedirs(db_dir)
            conn = sqlite3.connect(db_file_path)
            conn.close()
            flash(f'数据库文件创建成功: {db_file_path}', 'success')
    except Exception as e:
        logging.exception(f"创建数据库文件失败: {str(e)}")
        flash(f'创建数据库文件失败: {str(e)}', 'danger')
    return redirect(url_for('login'))

# 初始化数据库
@app.route('/init-database', methods=['POST'])
def init_database_route():
    try:
        db_file_path = resource_path('pms.db')
        if not os.path.exists(db_file_path):
            flash('请先创建数据库文件', 'warning')
        else:
            if init_database():
                flash('数据库初始化成功', 'success')
            else:
                flash('数据库初始化失败', 'danger')
    except Exception as e:
        logging.exception(f"初始化数据库失败: {str(e)}")
        flash(f'初始化数据库失败: {str(e)}', 'danger')
    
    return redirect(url_for('login'))

if __name__ == "__main__":
    # 确保实例目录存在
    instance_path = os.path.join(os.path.abspath("."), 'instance')
    if not os.path.exists(instance_path):
        os.makedirs(instance_path)

    # 先初始化数据库
    # logging.info("正在初始化数据库...")
    # try:
    #     init_success = init_database()
    #     if init_success:
    #         logging.info("数据库初始化成功")
    #     else:
    #         logging.error("数据库初始化失败，应用可能无法正常工作")
    # except Exception as e:
    #     logging.exception(f"数据库初始化时出错: {str(e)}")

    # 日志输出
    logging.info(f"工作目录: {os.getcwd()}")
    logging.info(f"数据库路径: {resource_path('pms.db')}")
    logging.info(f"模板路径: {resource_path('templates')}")
    logging.info(f"静态文件路径: {resource_path(os.path.join('src', 'static'))}")

    # 验证模板和静态文件目录
    templates_dir = resource_path('templates')
    static_dir = resource_path(os.path.join('src', 'static'))
    if not os.path.exists(templates_dir):
        logging.error(f"模板目录不存在: {templates_dir}")
    if not os.path.exists(static_dir):
        logging.error(f"静态文件目录不存在: {static_dir}")

    # 运行应用
    logging.info("启动应用服务器...")
    app.run(debug=True, host='0.0.0.0', port=5010)

# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
